home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / mswlogo3.zip / MSWLOGO.ZIP / EXAMPLES.ZIP / FSM < prev    next >
Text File  |  1993-04-12  |  8KB  |  329 lines

  1. ;
  2. ; Function:
  3. ;
  4. ; Finite State Machine Parser. See "MACH1-MACH10 at bottom"
  5. ;
  6. ; To run:
  7. ;
  8. ; Load "fsm
  9. ; Call GAME machinenumber
  10. ; Now enter character sequences that are legal for the machine
  11. ;
  12. ; Example:
  13. ;
  14. ; GAME 1
  15. ; aaaabbabababa (ACCEPTED)
  16. ; ababababababac (REJECTED, because "c" is not legal for machine 1)
  17. ;
  18. TO ACCEPT
  19. LOCAL "OLDPOS
  20. MAKE "OLDPOS CURSOR
  21. SETCURSOR [15 1]
  22. TYPE "ACCEPT
  23. SETCURSOR :OLDPOS
  24. END
  25.  
  26. TO ACCEPTPART :MACHINE
  27. OP LAST :MACHINE
  28. END
  29.  
  30. TO ARRANGE :MOVE
  31. LOCAL [FROM INPUT TO ARROW]
  32. MAKE "FROM FIRST :MOVE
  33. MAKE "INPUT FIRST BF :MOVE
  34. MAKE "TO LAST :MOVE
  35. MAKESTATE :FROM
  36. MAKESTATE :TO
  37. MAKE "ARROW WORD :FROM :INPUT
  38. IFELSE NAMEP :ARROW [ARRANGE.DUPLICATE :ARROW] [ARRANGE.UNSEEN :ARROW]
  39. END
  40.  
  41. TO ARRANGE.DUPLICATE :ARROW
  42. IF MEMBERP :TO THING :ARROW [STOP]
  43. MAKE "TROUBLE "TRUE
  44. MAKE :ARROW MERGE :TO THING :ARROW
  45. END
  46.  
  47. TO ARRANGE.UNSEEN :ARROW
  48. MAKE :FROM FPUT :INPUT THING :FROM
  49. TEMPMAKE :ARROW SINGLE :TO
  50. END
  51.  
  52. TO BLANK
  53. LOCAL "OLDPOS
  54. MAKE "OLDPOS CURSOR
  55. SETCURSOR [15 1]
  56. TYPE "|      |
  57. SETCURSOR :OLDPOS
  58. END
  59.  
  60. TO BUILD.STATE :STATE
  61. OP MAP [LINK :STATE ? (FIRST THING WORD :STATE ?)] THING :STATE
  62. END
  63.  
  64. TO DETERMINE :MACHINE
  65. LOCAL [NEWACCEPT ALLSTATES ALIASES TROUBLE TEMPNAMES NEWMOVES]
  66. MAKE "NEWACCEPT ACCEPTPART :MACHINE
  67. MAKE "ALLSTATES []
  68. MAKE "ALIASES []
  69. MAKE "TROUBLE "FALSE
  70. MAKE "TEMPNAMES []
  71. FOREACH MOVEPART :MACHINE [ARRANGE ?]
  72. IF NOT :TROUBLE [FOREACH :TEMPNAMES [ERN ?] OP :MACHINE]
  73. RESOLVE :ALLSTATES
  74. MAKE "NEWMOVES REBUILD :ALLSTATES
  75. FOREACH :TEMPNAMES [ERN ?]
  76. OP LINK (STARTPART :MACHINE) :NEWMOVES :NEWACCEPT
  77. END
  78.  
  79. TO FSM :MACHINE
  80. CT
  81. SETCURSOR [0 3]
  82. FSM1 FIRST :MACHINE FIRST :MACHINE FIRST BF :MACHINE LAST :MACHINE
  83. END
  84.  
  85. TO FSM1 :START :HERE :MOVES :ACCEPT
  86. IFELSE MEMBERP :HERE :ACCEPT [ACCEPT] [REJECT]
  87. FSM1 :START (FSMNEXT :START :HERE RC :MOVES) :MOVES :ACCEPT
  88. END
  89.  
  90. TO FSMNEXT :START :HERE :INPUT :MOVES
  91. BLANK
  92. TYPE :INPUT
  93. IF EQUALP :INPUT CHAR 13 [TYPE CHAR 10  OP :START]
  94. CATCH "ERROR [OP LAST FIND [FSMTEST :HERE :INPUT ?] :MOVES]
  95. OP -1
  96. END
  97.  
  98. TO FSMTEST :HERE :INPUT :MOVE
  99. OP AND (EQUALP :HERE FIRST :MOVE) (EQUALP :INPUT FIRST BF :MOVE)
  100. END
  101.  
  102. TO GAME :WHICH
  103. FSM THING WORD "MACH :WHICH
  104. END
  105.  
  106. TO GETALIAS :LIST
  107. CATCH "ERROR [OP FIRST FIND [EQUALP :LIST LAST ?] :ALIASES]
  108. OP []
  109. END
  110.  
  111. TO LINK :ONE :TWO :THREE
  112. OP (LIST :ONE :TWO :THREE)
  113. END
  114.  
  115. TO MACHINE :REGEXP
  116. LOCAL "NEXTSTATE
  117. MAKE "NEXTSTATE 0
  118. OP OPTIMIZE DETERMINE NONDET :REGEXP
  119. END
  120.  
  121. TO MAKESTATE :STATE
  122. IF MEMBERP :STATE :ALLSTATES [STOP]
  123. MAKE "ALLSTATES FPUT :STATE :ALLSTATES
  124. TEMPMAKE :STATE []
  125. END
  126.  
  127. TO MANY.MOVES :PARTMOVE :ACCEPT
  128. FOREACH :ACCEPT [NEWMOVES SINGLE FPUT ? :PARTMOVE]
  129. END
  130.  
  131. TO MAPND :EXPRS
  132. OP MAP [NONDET ?] :EXPRS
  133. END
  134.  
  135. TO MERGE :NEW :LIST
  136. IF EMPTYP :LIST [OP FPUT :NEW []]
  137. IF :NEW < FIRST :LIST [OP FPUT :NEW :LIST]
  138. OP FPUT FIRST :LIST MERGE :NEW BF :LIST
  139. END
  140.  
  141. TO MOVEPART :MACHINE
  142. OP FIRST BF :MACHINE
  143. END
  144.  
  145. TO NDCONCAT :EXPRS
  146. OP REDUCE "STRING MAPND :EXPRS
  147. END
  148.  
  149. TO NDLETTER :LETTER
  150. LOCAL [FROM TO]
  151. MAKE "FROM NEWSTATE
  152. MAKE "TO NEWSTATE
  153. OP LINK :FROM (SINGLE (LINK :FROM :LETTER :TO)) (SINGLE :TO)
  154. END
  155.  
  156. TO NDMANY :REGEXP
  157. OP NDMANY1 NONDET :REGEXP
  158. END
  159.  
  160. TO NDMANY1 :MACHINE
  161. LOCAL [START MOVES ACCEPT]
  162. MAKE "START STARTPART :MACHINE
  163. MAKE "MOVES MOVEPART :MACHINE
  164. MAKE "ACCEPT ACCEPTPART :MACHINE
  165. FOREACH :MOVES [IF EQUALP :START FIRST ? [MANY.MOVES BF ? :ACCEPT]]
  166. OP LINK :START :MOVES (FPUT :START :ACCEPT)
  167. END
  168.  
  169. TO NDOR :EXPRS
  170. OP UNION NEWSTATE MAPND :EXPRS
  171. END
  172.  
  173. TO NEWACCEPT :NEW
  174. IF NOT MEMBERP :NEW :ACCEPT [MAKE "ACCEPT SE :NEW :ACCEPT]
  175. END
  176.  
  177. TO NEWMOVES :NEW
  178. MAKE "MOVES SE :NEW :MOVES
  179. END
  180.  
  181. TO NEWSTATE
  182. MAKE "NEXTSTATE :NEXTSTATE+1
  183. OP :NEXTSTATE
  184. END
  185.  
  186. TO NONDET :REGEXP
  187. IF WORDP :REGEXP [OP NDLETTER :REGEXP]
  188. IF EQUALP FIRST :REGEXP "OR [OP NDOR BF :REGEXP]
  189. IF EQUALP FIRST :REGEXP "* [OP NDMANY LAST :REGEXP]
  190. OP NDCONCAT :REGEXP
  191. END
  192.  
  193. TO OPTIMIZE :MACHINE
  194. LOCAL [START MOVES ACCEPT GOODSTATES GOODMOVES OLDMOVES]
  195. MAKE "START STARTPART :MACHINE
  196. MAKE "MOVES MOVEPART :MACHINE
  197. MAKE "ACCEPT ACCEPTPART :MACHINE
  198. MAKE "GOODSTATES SINGLE STARTPART :MACHINE
  199. MAKE "GOODMOVES []
  200. DO.UNTIL [MAKE "OLDMOVES :GOODMOVES ~
  201.           MAKE "MOVES FILTER [OPTIMIZE2 ?] :MOVES] ~
  202.          [EQUALP :OLDMOVES :GOODMOVES]
  203. OP LINK :START :GOODMOVES (FILTER [MEMBERP ? :GOODSTATES] :ACCEPT)
  204. END
  205.  
  206. TO OPTIMIZE2 :MOVE
  207. IF NOT MEMBERP FIRST :MOVE :GOODSTATES [OP "TRUE]
  208. MAKE "GOODMOVES FPUT :MOVE :GOODMOVES
  209. IF NOT MEMBERP LAST :MOVE :GOODSTATES ~
  210.    [MAKE "GOODSTATES FPUT LAST :MOVE :GOODSTATES]
  211. OP "FALSE
  212. END
  213.  
  214. TO REBUILD :STATELIST
  215. OP MAP.SE [BUILD.STATE ?] :STATELIST
  216. END
  217.  
  218. TO REJECT
  219. LOCAL "OLDPOS
  220. MAKE "OLDPOS CURSOR
  221. SETCURSOR [15 1]
  222. TYPE "REJECT
  223. SETCURSOR :OLDPOS
  224. END
  225.  
  226. TO RESOLVE :STATES
  227. IF EMPTYP :STATES [STOP]
  228. LOCAL "STATE
  229. MAKE "STATE FIRST :STATES
  230. RESOLVE SE (BF :STATES) ~
  231.            (MAP.SE [RESOLVE.ARROW WORD :STATE ?] THING :STATE)
  232. END
  233.  
  234. TO RESOLVE.ARROW :ARROW
  235. LOCAL [DESTINATIONS ALIAS]
  236. MAKE "DESTINATIONS THING :ARROW
  237. IF EMPTYP BF :DESTINATIONS [OP []]
  238. MAKE "ALIAS GETALIAS :DESTINATIONS
  239. IF NOT EMPTYP :ALIAS [MAKE :ARROW SINGLE :ALIAS OP []]
  240. MAKE "ALIAS NEWSTATE
  241. MAKESTATE :ALIAS
  242. MAKE :ARROW SINGLE :ALIAS
  243. MAKE "ALIASES FPUT (LIST :ALIAS :DESTINATIONS) :ALIASES
  244. FOREACH :DESTINATIONS [SETUPALIAS ?]
  245. OP :ALIAS
  246. END
  247.  
  248. TO SETA.INPUT :STATE :INPUT
  249. FOREACH (THING WORD :STATE :INPUT) [ARRANGE LINK :ALIAS :INPUT ?]
  250. END
  251.  
  252. TO SETUPALIAS :STATE
  253. IF AND (MEMBERP :STATE :NEWACCEPT) (NOT MEMBERP :ALIAS :NEWACCEPT) ~
  254.    [MAKE "NEWACCEPT FPUT :ALIAS :NEWACCEPT]
  255. FOREACH THING :STATE [SETA.INPUT :STATE ?]
  256. END
  257.  
  258. TO SINGLE :THING
  259. OP (LIST :THING)
  260. END
  261.  
  262. TO STARTPART :MACHINE
  263. OP FIRST :MACHINE
  264. END
  265.  
  266. TO STRING :MACHINE :OTHERS
  267. LOCAL [START MOVES ACCEPT OTHERSTART OTHERMOVES OTHERACCEPT]
  268. MAKE "START STARTPART :MACHINE
  269. MAKE "MOVES MOVEPART :MACHINE
  270. MAKE "ACCEPT ACCEPTPART :MACHINE
  271. MAKE "OTHERSTART STARTPART :OTHERS
  272. MAKE "OTHERMOVES MOVEPART :OTHERS
  273. MAKE "OTHERACCEPT ACCEPTPART :OTHERS
  274. OP LINK :START ~
  275.         (SE :MOVES ~
  276.             (STRING.SPLICE :ACCEPT :OTHERSTART :OTHERMOVES) ~
  277.             :OTHERMOVES) ~
  278.         (STRINGA :ACCEPT :OTHERSTART :OTHERACCEPT)
  279. END
  280.  
  281. TO STRING.COPY :ACCEPT :OTHERSTART :MOVE
  282. OP IFELSE EQUALP :OTHERSTART FIRST :MOVE [MAP [FPUT ? BF :MOVE] :ACCEPT] [[]]
  283. END
  284.  
  285. TO STRING.SPLICE :ACCEPT :OTHERSTART :OTHERMOVES
  286. OP MAP.SE [STRING.COPY :ACCEPT :OTHERSTART ?] :OTHERMOVES
  287. END
  288.  
  289. TO STRINGA :ACCEPT :OTHERSTART :OTHERACCEPT
  290. IF MEMBERP :OTHERSTART :OTHERACCEPT [OP SE :ACCEPT :OTHERACCEPT]
  291. OP :OTHERACCEPT
  292. END
  293.  
  294. TO TEMPMAKE :VAR :VAL
  295. MAKE "TEMPNAMES FPUT :VAR :TEMPNAMES
  296. MAKE :VAR :VAL
  297. END
  298.  
  299. TO UNION :START :MACHINES
  300. LOCAL [MOVES ACCEPT]
  301. MAKE "MOVES []
  302. MAKE "ACCEPT []
  303. FOREACH :MACHINES [UNION1 ?]
  304. OUTPUT LINK :START :MOVES :ACCEPT
  305. END
  306.  
  307. TO UNION1 :MACHINE
  308. NEWMOVES MOVEPART :MACHINE
  309. NEWMOVES MAP [FPUT :START BF ?] ~
  310.              FILTER [EQUALP (STARTPART :MACHINE) (FIRST ?)] MOVEPART :MACHINE
  311. NEWACCEPT ACCEPTPART :MACHINE
  312. IF MEMBERP (STARTPART :MACHINE) (ACCEPTPART :MACHINE) ~
  313.    [NEWACCEPT :START]
  314. END
  315.  
  316. MAKE "MACH1 [1 [[1 A 1] [1 B 1]] [1]]
  317. MAKE "MACH10 [1 [[1 A 1] [1 B 1] [1 C 2] [2 A 3] [2 B 1] [3 A 1]] [1]]
  318. MAKE "MACH2 [1 [[1 A 2] [1 B 2] [1 C 2] [2 A 1] [2 B 1] [2 C 1]] [1]]
  319. MAKE "MACH3 [1 [[1 A 2] [2 B 3] [3 A 3] [3 B 3] [3 C 3]] [3]]
  320. MAKE "MACH4 [1 [[1 A 2] [1 B 3] [1 C 4] [2 A 1] [3 B 1] [4 C 1]] [1]]
  321. MAKE "MACH5 [1 [[1 A 2] [1 B 2] [1 C 2] [2 B 1]] [1]]
  322. MAKE "MACH6 [1 [[1 A 2] [2 A 2] [2 B 2] [2 C 3] [3 A 2] [3 B 2] [3 C 3]] [3]]
  323. MAKE "MACH7 [1 [[1 A 1] [1 B 1] [1 C 2] [2 C 1]] [1]]
  324. MAKE "MACH8 [1 [[1 A 2] [1 B 1] [1 C 1] [2 A 1] [2 B 2] [2 C 2]] [1]]
  325. MAKE "MACH9 [1 [[1 A 2] [1 B 1] [1 C 1] [2 A 2] [2 B 3] [2 C 1] [3 A 2] ~
  326.                 [3 B 1] [3 C 4] [4 A 2] [4 B 5] [4 C 1] [5 A 6] [5 B 1] ~
  327.                 [5 C 1] [6 A 6] [6 B 6] [6 C 6]] ~
  328.              [6]]
  329.